package com.menghao.sso.server.controller;

import com.menghao.sso.server.exception.ValidateFailException;
import com.menghao.sso.server.model.SimpleService;
import com.menghao.sso.server.model.credentials.UsernamePasswordCredentials;
import com.menghao.sso.server.service.AuthenticationService;
import com.menghao.sso.server.service.AuthorizationService;
import com.menghao.sso.server.util.CommonUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;

/**
 * <p>登录Controller.<br>
 *
 * @author menghao.
 * @version 2017/11/16.
 */
@Controller
@RequestMapping(CommonUtils.LOGIN_URL)
public class LoginController {

    @Autowired
    private AuthenticationService authenticationService;
    @Autowired
    private AuthorizationService authorizationService;

    /**
     * 跳转统一登录
     *
     * @param service 请求服务url
     * @return String
     */
    @GetMapping
    public String loginPage(Model model, String service, String msg) throws UnsupportedEncodingException {
        model.addAttribute(CommonUtils.SERVICE, service);
        if (StringUtils.hasText(msg)) {
            model.addAttribute(CommonUtils.MSG, URLDecoder.decode(msg, "UTF-8"));
        }
        return "/login";
    }

    /**
     * 用户登录
     *
     * @param request  请求（包含用户名、密码、请求url）
     * @param response 响应（添加cookie、重定向）
     * @return String
     */
    @PostMapping
    public String login(HttpServletRequest request, HttpServletResponse response, Model model) throws IOException, ValidateFailException {
        String username = request.getParameter(CommonUtils.USERNAME);
        String password = request.getParameter(CommonUtils.PASSWORD);
        String service = request.getParameter(CommonUtils.SERVICE);
        UsernamePasswordCredentials credentials = UsernamePasswordCredentials.builder()
                .username(username).password(password).build();
        try {
            authenticationService.validateCredentials(credentials);
        } catch (ValidateFailException e) {
            throw new ValidateFailException(service, e.getMsg());
        }

        String tgtId = null;
        String stId = null;
        try {
            tgtId = authorizationService.createTicketGrantingTicket(credentials);
            stId = authorizationService.createServiceTicket(tgtId, new SimpleService(service));
        } catch (ValidateFailException e) {
            throw new ValidateFailException(service, e.getMsg());
        }
        createCookie(response, tgtId);
        StringBuilder builder = new StringBuilder(service);
        if (service.contains("?")) {
            builder.append("&");
        } else {
            builder.append("?");
        }
        builder.append(CommonUtils.ST_ID).append("=").append(stId);
        response.sendRedirect(builder.toString());
        return null;

    }

    private void createCookie(HttpServletResponse response, String tgtId) {
        Cookie cookie = new Cookie(CommonUtils.TGT_ID, tgtId);
        cookie.setDomain(CommonUtils.DOMAIN);
        cookie.setPath("/");
        cookie.setMaxAge(-1);
        response.addCookie(cookie);
    }
}
